home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MOR55SRC.ZIP / MORIA / SOURCE / SPELLS.C < prev    next >
C/C++ Source or Header  |  1992-12-07  |  60KB  |  2,604 lines

  1. /* source/spells.c: player/creature spells, breaths, wands, scrolls, etc. code
  2.  
  3.    Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
  4.  
  5.    This software may be copied and distributed for educational, research, and
  6.    not for profit purposes provided that this copyright and statement are
  7.    included in all such copies. */
  8.  
  9. #ifdef __TURBOC__
  10. #include    <stdio.h>
  11. #include    <stdlib.h>
  12. #endif /* __TURBOC__ */
  13.  
  14. #include "config.h"
  15. #include "constant.h"
  16. #include "types.h"
  17. #include "externs.h"
  18.  
  19. #ifdef USG
  20. #ifndef ATARIST_MWC
  21. #include <string.h>
  22. #endif
  23. #else
  24. #include <strings.h>
  25. #endif
  26.  
  27. #if defined(LINT_ARGS)
  28. static void replace_spot(int, int, int);
  29. #else
  30. static void replace_spot();
  31. #endif
  32.  
  33. /* Following are spell procedure/functions            -RAK-    */
  34. /* These routines are commonly used in the scroll, potion, wands, and     */
  35. /* staves routines, and are occasionally called from other areas.      */
  36. /* Now included are creature spells also.               -RAK    */
  37.  
  38. void monster_name (m_name, m_ptr, r_ptr)
  39. char *m_name;
  40. monster_type *m_ptr;
  41. creature_type *r_ptr;
  42. {
  43.   if (!m_ptr->ml)
  44.     (void) strcpy (m_name, "It");
  45.   else
  46.     (void) sprintf (m_name, "The %s", r_ptr->name);
  47. }
  48.  
  49. void lower_monster_name (m_name, m_ptr, r_ptr)
  50. char *m_name;
  51. monster_type *m_ptr;
  52. creature_type *r_ptr;
  53. {
  54.   if (!m_ptr->ml)
  55.     (void) strcpy (m_name, "it");
  56.   else
  57.     (void) sprintf (m_name, "the %s", r_ptr->name);
  58. }
  59.  
  60. /* Sleep creatures adjacent to player            -RAK-    */
  61. int sleep_monsters1(y, x)
  62. int y, x;
  63. {
  64.   register int i, j;
  65.   register cave_type *c_ptr;
  66.   register monster_type *m_ptr;
  67.   register creature_type *r_ptr;
  68.   int sleep;
  69.   vtype out_val, m_name;
  70.  
  71.   sleep = FALSE;
  72.   for (i = y-1; i <= y+1; i++)
  73.     for (j = x-1; j <= x+1; j++)
  74.       {
  75.     c_ptr = &cave[i][j];
  76.     if (c_ptr->cptr > 1)
  77.       {
  78.         m_ptr = &m_list[c_ptr->cptr];
  79.         r_ptr = &c_list[m_ptr->mptr];
  80.  
  81.         monster_name (m_name, m_ptr, r_ptr);
  82.         if ((randint(MAX_MONS_LEVEL) < r_ptr->level) ||
  83.         (CD_NO_SLEEP & r_ptr->cdefense))
  84.           {
  85.         if (m_ptr->ml && (r_ptr->cdefense & CD_NO_SLEEP))
  86.           c_recall[m_ptr->mptr].r_cdefense |= CD_NO_SLEEP;
  87.         (void) sprintf(out_val, "%s is unaffected.", m_name);
  88.         msg_print(out_val);
  89.           }
  90.         else
  91.           {
  92.         sleep = TRUE;
  93.         m_ptr->csleep = 500;
  94.         (void) sprintf(out_val, "%s falls asleep.", m_name);
  95.         msg_print(out_val);
  96.           }
  97.       }
  98.       }
  99.   return(sleep);
  100. }
  101.  
  102. /* Detect any treasure on the current panel        -RAK-    */
  103. int detect_treasure()
  104. {
  105.   register int i, j, detect;
  106.   register cave_type *c_ptr;
  107.  
  108.   detect = FALSE;
  109.   for (i = panel_row_min; i <= panel_row_max; i++)
  110.     for (j = panel_col_min; j <= panel_col_max; j++)
  111.       {
  112.     c_ptr = &cave[i][j];
  113.     if ((c_ptr->tptr != 0) && (t_list[c_ptr->tptr].tval == TV_GOLD) &&
  114.         !test_light(i, j))
  115.       {
  116.         c_ptr->fm = TRUE;
  117.         lite_spot(i, j);
  118.         detect = TRUE;
  119.       }
  120.       }
  121.   return(detect);
  122. }
  123.  
  124.  
  125. /* Detect all objects on the current panel        -RAK-    */
  126. int detect_object()
  127. {
  128.   register int i, j, detect;
  129.   register cave_type *c_ptr;
  130.  
  131.   detect = FALSE;
  132.   for (i = panel_row_min; i <= panel_row_max; i++)
  133.     for (j = panel_col_min; j <= panel_col_max; j++)
  134.       {
  135.     c_ptr = &cave[i][j];
  136.     if ((c_ptr->tptr != 0) && (t_list[c_ptr->tptr].tval < TV_MAX_OBJECT)
  137.         && !test_light(i, j))
  138.       {
  139.         c_ptr->fm = TRUE;
  140.         lite_spot(i, j);
  141.         detect = TRUE;
  142.       }
  143.       }
  144.   return(detect);
  145. }
  146.  
  147.  
  148. /* Locates and displays traps on current panel        -RAK-    */
  149. int detect_trap()
  150. {
  151.   register int i, j;
  152.   int detect;
  153.   register cave_type *c_ptr;
  154.   register inven_type *t_ptr;
  155.  
  156.   detect = FALSE;
  157.   for (i = panel_row_min; i <= panel_row_max; i++)
  158.     for (j = panel_col_min; j <= panel_col_max; j++)
  159.       {
  160.     c_ptr = &cave[i][j];
  161.     if (c_ptr->tptr != 0)
  162.       if (t_list[c_ptr->tptr].tval == TV_INVIS_TRAP)
  163.         {
  164.           c_ptr->fm = TRUE;
  165.           change_trap(i, j);
  166.           detect = TRUE;
  167.         }
  168.       else if (t_list[c_ptr->tptr].tval == TV_CHEST)
  169.         {
  170.           t_ptr = &t_list[c_ptr->tptr];
  171.           known2(t_ptr);
  172.         }
  173.       }
  174.   return(detect);
  175. }
  176.  
  177.  
  178. /* Locates and displays all secret doors on current panel -RAK-    */
  179. int detect_sdoor()
  180. {
  181.   register int i, j, detect;
  182.   register cave_type *c_ptr;
  183.  
  184.   detect = FALSE;
  185.   for (i = panel_row_min; i <= panel_row_max; i++)
  186.     for (j = panel_col_min; j <= panel_col_max; j++)
  187.       {
  188.     c_ptr = &cave[i][j];
  189.     if (c_ptr->tptr != 0)
  190.       /* Secret doors  */
  191.       if (t_list[c_ptr->tptr].tval == TV_SECRET_DOOR)
  192.         {
  193.           c_ptr->fm = TRUE;
  194.           change_trap(i, j);
  195.           detect = TRUE;
  196.         }
  197.     /* Staircases     */
  198.       else if (((t_list[c_ptr->tptr].tval == TV_UP_STAIR) ||
  199.             (t_list[c_ptr->tptr].tval == TV_DOWN_STAIR)) &&
  200.            !c_ptr->fm)
  201.         {
  202.           c_ptr->fm = TRUE;
  203.           lite_spot(i, j);
  204.           detect = TRUE;
  205.         }
  206.       }
  207.   return(detect);
  208. }
  209.  
  210.  
  211. /* Locates and displays all invisible creatures on current panel -RAK-*/
  212. int detect_invisible()
  213. {
  214.   register int i, flag;
  215.   register monster_type *m_ptr;
  216. #ifdef ATARIST_MWC
  217.   int32u holder;
  218. #endif
  219.  
  220.   flag = FALSE;
  221.   for (i = mfptr - 1; i >= MIN_MONIX; i--)
  222.     {
  223.       m_ptr = &m_list[i];
  224.       if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx) &&
  225. #ifdef ATARIST_MWC
  226.       ((holder = CM_INVISIBLE) & c_list[m_ptr->mptr].cmove))
  227. #else
  228.       (CM_INVISIBLE & c_list[m_ptr->mptr].cmove))
  229. #endif
  230.     {
  231.       m_ptr->ml = TRUE;
  232.       /* works correctly even if hallucinating */
  233.       print((char)c_list[m_ptr->mptr].cchar, (int)m_ptr->fy,
  234.         (int)m_ptr->fx);
  235.       flag = TRUE;
  236.     }
  237.     }
  238.   if (flag)
  239.     {
  240.       msg_print("You sense the presence of invisible creatures!");
  241.       msg_print(CNIL);
  242.       /* must unlight every monster just lighted */
  243.       creatures(FALSE);
  244.     }
  245.   return(flag);
  246. }
  247.  
  248.  
  249. /* Light an area: 1.  If corridor  light immediate area -RAK-*/
  250. /*          2.  If room  light entire room plus immediate area.     */
  251. int light_area(y, x)
  252. register int y, x;
  253. {
  254.   register int i, j, light;
  255.  
  256.   if (py.flags.blind < 1)
  257.     msg_print("You are surrounded by a white light.");
  258.   light = TRUE;
  259.   if (cave[y][x].lr && (dun_level > 0))
  260.     light_room(y, x);
  261.   /* Must always light immediate area, because one might be standing on
  262.      the edge of a room, or next to a destroyed area, etc.  */
  263.   for (i = y-1; i <= y+1; i++)
  264.     for (j = x-1; j <=  x+1; j++)
  265.       {
  266.     cave[i][j].pl = TRUE;
  267.     lite_spot(i, j);
  268.       }
  269.   return(light);
  270. }
  271.  
  272.  
  273. /* Darken an area, opposite of light area        -RAK-    */
  274. int unlight_area(y, x)
  275. int y, x;
  276. {
  277.   register int i, j;
  278.   int tmp1, tmp2, unlight;
  279.   int start_row, start_col, end_row, end_col;
  280.   register cave_type *c_ptr;
  281.  
  282.   unlight = FALSE;
  283.   if (cave[y][x].lr && (dun_level > 0))
  284.     {
  285.       tmp1 = (SCREEN_HEIGHT/2);
  286.       tmp2 = (SCREEN_WIDTH /2);
  287.       start_row = (y/tmp1)*tmp1 + 1;
  288.       start_col = (x/tmp2)*tmp2 + 1;
  289.       end_row = start_row + tmp1 - 1;
  290.       end_col = start_col + tmp2 - 1;
  291.       for (i = start_row; i <= end_row; i++)
  292.     {
  293.       for (j = start_col; j <= end_col; j++)
  294.         {
  295.           c_ptr = &cave[i][j];
  296.           if (c_ptr->lr && c_ptr->fval <= MAX_CAVE_FLOOR)
  297.         {
  298.           c_ptr->pl = FALSE;
  299.           c_ptr->fval = DARK_FLOOR;
  300.           lite_spot (i, j);
  301.           if (!test_light(i, j))
  302.             unlight = TRUE;
  303.         }
  304.         }
  305.     }
  306.     }
  307.   else
  308.     for (i = y-1; i <= y+1; i++)
  309.       for (j = x-1; j <= x+1; j++)
  310.     {
  311.       c_ptr = &cave[i][j];
  312.       if ((c_ptr->fval == CORR_FLOOR) && c_ptr->pl)
  313.         {
  314.           /* pl could have been set by star-lite wand, etc */
  315.           c_ptr->pl = FALSE;
  316.           unlight = TRUE;
  317.         }
  318.     }
  319.  
  320.   if (unlight && py.flags.blind <= 0)
  321.     msg_print("Darkness surrounds you.");
  322.  
  323.   return(unlight);
  324. }
  325.  
  326.  
  327. /* Map the current area plus some            -RAK-    */
  328. void map_area()
  329. {
  330.   register cave_type *c_ptr;
  331.   register int i7, i8, n, m;
  332.   int i, j, k, l;
  333.  
  334.   i = panel_row_min - randint(10);
  335.   j = panel_row_max + randint(10);
  336.   k = panel_col_min - randint(20);
  337.   l = panel_col_max + randint(20);
  338.   for (m = i; m <= j; m++)
  339.     for (n = k; n <= l; n++)
  340.       if (in_bounds(m, n) && (cave[m][n].fval <= MAX_CAVE_FLOOR))
  341.     for (i7 = m-1; i7 <= m+1; i7++)
  342.       for (i8 = n-1; i8 <= n+1; i8++)
  343.         {
  344.           c_ptr = &cave[i7][i8];
  345.           if (c_ptr->fval >= MIN_CAVE_WALL)
  346.         c_ptr->pl = TRUE;
  347.           else if ((c_ptr->tptr != 0) &&
  348.                (t_list[c_ptr->tptr].tval >= TV_MIN_VISIBLE) &&
  349.                (t_list[c_ptr->tptr].tval <= TV_MAX_VISIBLE))
  350.         c_ptr->fm = TRUE;
  351.         }
  352.   prt_map();
  353. }
  354.  
  355.  
  356. /* Identify an object                    -RAK-    */
  357. int ident_spell()
  358. {
  359.   int item_val;
  360.   bigvtype out_val, tmp_str;
  361.   register int ident;
  362.   register inven_type *i_ptr;
  363.  
  364.   ident = FALSE;
  365.   if (get_item(&item_val, "Item you wish identified?", 0, INVEN_ARRAY_SIZE,
  366.            CNIL, CNIL))
  367.     {
  368.       ident = TRUE;
  369.       identify(&item_val);
  370.       i_ptr = &inventory[item_val];
  371.       known2(i_ptr);
  372.       objdes(tmp_str, i_ptr, TRUE);
  373.       if (item_val >= INVEN_WIELD)
  374.     {
  375.       calc_bonuses();
  376.       (void) sprintf (out_val, "%s: %s", describe_use(item_val), tmp_str);
  377.     }
  378.       else
  379.     (void) sprintf(out_val, "%c %s", item_val+97, tmp_str);
  380.       msg_print(out_val);
  381.     }
  382.   return(ident);
  383. }
  384.  
  385.  
  386. /* Get all the monsters on the level pissed off.    -RAK-    */
  387. int aggravate_monster (dis_affect)
  388. int dis_affect;
  389. {
  390.   register int i, aggravate;
  391.   register monster_type *m_ptr;
  392.  
  393.   aggravate = FALSE;
  394.   for (i = mfptr - 1; i >= MIN_MONIX; i--)
  395.     {
  396.       m_ptr = &m_list[i];
  397.       m_ptr->csleep = 0;
  398.       if ((m_ptr->cdis <= dis_affect) && (m_ptr->cspeed < 2))
  399.     {
  400.       m_ptr->cspeed++;
  401.       aggravate = TRUE;
  402.     }
  403.     }
  404.   if (aggravate)
  405.     msg_print ("You hear a sudden stirring in the distance!");
  406.   return(aggravate);
  407. }
  408.  
  409.  
  410. /* Surround the fool with traps (chuckle)        -RAK-    */
  411. int trap_creation()
  412. {
  413.   register int i, j, trap;
  414.   register cave_type *c_ptr;
  415.  
  416.   trap = TRUE;
  417.   for (i = char_row-1; i <= char_row+1; i++)
  418.     for (j = char_col-1; j <= char_col+1; j++)
  419.       {
  420.     /* Don't put a trap under the player, since this can lead to
  421.        strange situations, e.g. falling through a trap door while
  422.        trying to rest, setting off a falling rock trap and ending
  423.        up under the rock.  */
  424.     if (i == char_row && j == char_col)
  425.       continue;
  426.     c_ptr = &cave[i][j];
  427.     if (c_ptr->fval <= MAX_CAVE_FLOOR)
  428.       {
  429.         if (c_ptr->tptr != 0)
  430.           (void) delete_object(i, j);
  431.         place_trap(i, j, randint(MAX_TRAP)-1);
  432.         /* don't let player gain exp from the newly created traps */
  433.         t_list[c_ptr->tptr].p1 = 0;
  434.         /* open pits are immediately visible, so call lite_spot */
  435.         lite_spot(i, j);
  436.       }
  437.       }
  438.   return(trap);
  439. }
  440.  
  441.  
  442. /* Surround the player with doors.            -RAK-    */
  443. int door_creation()
  444. {
  445.   register int i, j, door;
  446.   int k;
  447.   register cave_type *c_ptr;
  448.  
  449.   door = FALSE;
  450.   for (i = char_row-1; i <= char_row+1; i++)
  451.     for (j = char_col-1; j <=  char_col+1; j++)
  452.       if ((i != char_row) || (j != char_col))
  453.     {
  454.       c_ptr = &cave[i][j];
  455.       if (c_ptr->fval <= MAX_CAVE_FLOOR)
  456.         {
  457.           door = TRUE;
  458.           if (c_ptr->tptr != 0)
  459.         (void) delete_object(i, j);
  460.           k = popt();
  461.           c_ptr->fval = BLOCKED_FLOOR;
  462.           c_ptr->tptr = k;
  463.           invcopy(&t_list[k], OBJ_CLOSED_DOOR);
  464.           lite_spot(i, j);
  465.         }
  466.     }
  467.   return(door);
  468. }
  469.  
  470.  
  471. /* Destroys any adjacent door(s)/trap(s)        -RAK-    */
  472. int td_destroy()
  473. {
  474.   register int i, j, destroy;
  475.   register cave_type *c_ptr;
  476.  
  477.   destroy = FALSE;
  478.   for (i = char_row-1; i <= char_row+1; i++)
  479.     for (j = char_col-1; j <= char_col+1; j++)
  480.       {
  481.     c_ptr = &cave[i][j];
  482.     if (c_ptr->tptr != 0)
  483.       {
  484.         if (((t_list[c_ptr->tptr].tval >= TV_INVIS_TRAP) &&
  485.          (t_list[c_ptr->tptr].tval <= TV_CLOSED_DOOR) &&
  486.          (t_list[c_ptr->tptr].tval != TV_RUBBLE)) ||
  487.         (t_list[c_ptr->tptr].tval == TV_SECRET_DOOR))
  488.           {
  489.         if (delete_object(i, j))
  490.           destroy = TRUE;
  491.           }
  492.         else if (t_list[c_ptr->tptr].tval == TV_CHEST)
  493.           {
  494.         /* destroy traps on chest and unlock */
  495.         t_list[c_ptr->tptr].flags &= ~(CH_TRAPPED|CH_LOCKED);
  496.         t_list[c_ptr->tptr].name2 = SN_UNLOCKED;
  497.         msg_print ("You have disarmed the chest.");
  498.         known2(&t_list[c_ptr->tptr]);
  499.         destroy = TRUE;
  500.           }
  501.       }
  502.       }
  503.   return(destroy);
  504. }
  505.  
  506.  
  507. /* Display all creatures on the current panel        -RAK-    */
  508. int detect_monsters()
  509. {
  510.   register int i, detect;
  511.   register monster_type *m_ptr;
  512. #ifdef ATARIST_MWC
  513.   int32u holder;
  514. #endif
  515.  
  516.   detect = FALSE;
  517.   for (i = mfptr - 1; i >= MIN_MONIX; i--)
  518.     {
  519.       m_ptr = &m_list[i];
  520.       if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx) &&
  521. #ifdef ATARIST_MWC
  522.       (((holder = CM_INVISIBLE) & c_list[m_ptr->mptr].cmove) == 0))
  523. #else
  524.       ((CM_INVISIBLE & c_list[m_ptr->mptr].cmove) == 0))
  525. #endif
  526.     {
  527.       m_ptr->ml = TRUE;
  528.       /* works correctly even if hallucinating */
  529.       print((char)c_list[m_ptr->mptr].cchar, (int)m_ptr->fy,
  530.         (int)m_ptr->fx);
  531.       detect = TRUE;
  532.     }
  533.     }
  534.   if (detect)
  535.     {
  536.       msg_print("You sense the presence of monsters!");
  537.       msg_print(CNIL);
  538.       /* must unlight every monster just lighted */
  539.       creatures(FALSE);
  540.     }
  541.   return(detect);
  542. }
  543.  
  544.  
  545. /* Leave a line of light in given dir, blue light can sometimes    */
  546. /* hurt creatures.                       -RAK-   */
  547. void light_line(dir, y, x)
  548. int dir, y, x;
  549. {
  550.   register int i;
  551.   register cave_type *c_ptr;
  552.   register monster_type *m_ptr;
  553.   register creature_type *r_ptr;
  554.   int dist, flag;
  555.   vtype out_val, m_name;
  556.  
  557.   dist = -1;
  558.   flag = FALSE;
  559.   do
  560.     {
  561.       /* put mmove at end because want to light up current spot */
  562.       dist++;
  563.       c_ptr = &cave[y][x];
  564.       if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
  565.     flag = TRUE;
  566.       else
  567.     {
  568.       if (!c_ptr->pl && !c_ptr->tl)
  569.         {
  570.           /* set pl so that lite_spot will work */
  571.           c_ptr->pl = TRUE;
  572.           if (c_ptr->fval == LIGHT_FLOOR)
  573.         {
  574.           if (panel_contains(y, x))
  575.             light_room(y, x);
  576.         }
  577.           else
  578.         lite_spot(y, x);
  579.         }
  580.       /* set pl in case tl was true above */
  581.       c_ptr->pl = TRUE;
  582.       if (c_ptr->cptr > 1)
  583.         {
  584.           m_ptr = &m_list[c_ptr->cptr];
  585.           r_ptr = &c_list[m_ptr->mptr];
  586.           /* light up and draw monster */
  587.           update_mon ((int)c_ptr->cptr);
  588.           monster_name (m_name, m_ptr, r_ptr);
  589.           if (CD_LIGHT & r_ptr->cdefense)
  590.         {
  591.           if (m_ptr->ml)
  592.             c_recall[m_ptr->mptr].r_cdefense |= CD_LIGHT;
  593.           i = mon_take_hit((int)c_ptr->cptr, damroll(2, 8));
  594.           if (i >= 0)
  595.             {
  596.               (void) sprintf(out_val,
  597.                  "%s shrivels away in the light!", m_name);
  598.               msg_print(out_val);
  599.               prt_experience();
  600.             }
  601.           else
  602.             {
  603.               (void) sprintf(out_val, "%s cringes from the light!",
  604.                      m_name);
  605.               msg_print (out_val);
  606.             }
  607.         }
  608.         }
  609.     }
  610.       (void) mmove(dir, &y, &x);
  611.     }
  612.   while (!flag);
  613. }
  614.  
  615.  
  616. /* Light line in all directions                -RAK-    */
  617. void starlite(y, x)
  618. register int y, x;
  619. {
  620.   register int i;
  621.  
  622.   if (py.flags.blind < 1)
  623.     msg_print("The end of the staff bursts into a blue shimmering light.");
  624.   for (i = 1; i <= 9; i++)
  625.     if (i != 5)
  626.       light_line(i, y, x);
  627. }
  628.  
  629.  
  630. /* Disarms all traps/chests in a given direction    -RAK-    */
  631. int disarm_all(dir, y, x)
  632. int dir, y, x;
  633. {
  634.   register cave_type *c_ptr;
  635.   register inven_type *t_ptr;
  636.   register int disarm, dist;
  637.  
  638.   disarm = FALSE;
  639.   dist = -1;
  640.   do
  641.     {
  642.       /* put mmove at end, in case standing on a trap */
  643.       dist++;
  644.       c_ptr = &cave[y][x];
  645.       /* note, must continue upto and including the first non open space,
  646.      because secret doors have fval greater than MAX_OPEN_SPACE */
  647.       if (c_ptr->tptr != 0)
  648.     {
  649.       t_ptr = &t_list[c_ptr->tptr];
  650.       if ((t_ptr->tval == TV_INVIS_TRAP) || (t_ptr->tval == TV_VIS_TRAP))
  651.         {
  652.           if (delete_object(y, x))
  653.         disarm = TRUE;
  654.         }
  655.       else if (t_ptr->tval == TV_CLOSED_DOOR)
  656.         t_ptr->p1 = 0;  /* Locked or jammed doors become merely closed. */
  657.       else if (t_ptr->tval == TV_SECRET_DOOR)
  658.         {
  659.           c_ptr->fm = TRUE;
  660.           change_trap(y, x);
  661.           disarm = TRUE;
  662.         }
  663.       else if ((t_ptr->tval == TV_CHEST) && (t_ptr->flags != 0))
  664.         {
  665.           msg_print("Click!");
  666.           t_ptr->flags &= ~(CH_TRAPPED|CH_LOCKED);
  667.           disarm = TRUE;
  668.           t_ptr->name2 = SN_UNLOCKED;
  669.           known2(t_ptr);
  670.         }
  671.     }
  672.       (void) mmove(dir, &y, &x);
  673.     }
  674.   while ((dist <= OBJ_BOLT_RANGE) && c_ptr->fval <= MAX_OPEN_SPACE);
  675.   return(disarm);
  676. }
  677.  
  678.  
  679. /* Return flags for given type area affect        -RAK-    */
  680. void get_flags(typ, weapon_type, harm_type, destroy)
  681. int typ;
  682. int32u *weapon_type; int *harm_type;
  683. int (**destroy)();
  684. {
  685.   switch(typ)
  686.     {
  687.     case GF_MAGIC_MISSILE:
  688.       *weapon_type = 0;
  689.       *harm_type   = 0;
  690.       *destroy       = set_null;
  691.       break;
  692.     case GF_LIGHTNING:
  693.       *weapon_type = CS_BR_LIGHT;
  694.       *harm_type   = CD_LIGHT;
  695.       *destroy       = set_lightning_destroy;
  696.       break;
  697.     case GF_POISON_GAS:
  698.       *weapon_type = CS_BR_GAS;
  699.       *harm_type   = CD_POISON;
  700.       *destroy       = set_null;
  701.       break;
  702.     case GF_ACID:
  703.       *weapon_type = CS_BR_ACID;
  704.       *harm_type   = CD_ACID;
  705.       *destroy       = set_acid_destroy;
  706.       break;
  707.     case GF_FROST:
  708.       *weapon_type = CS_BR_FROST;
  709.       *harm_type   = CD_FROST;
  710.       *destroy       = set_frost_destroy;
  711.       break;
  712.     case GF_FIRE:
  713.       *weapon_type = CS_BR_FIRE;
  714.       *harm_type   = CD_FIRE;
  715.       *destroy       = set_fire_destroy;
  716.       break;
  717.     case GF_HOLY_ORB:
  718.       *weapon_type = 0;
  719.       *harm_type   = CD_EVIL;
  720.       *destroy       = set_null;
  721.       break;
  722.     default:
  723.       msg_print("ERROR in get_flags()\n");
  724.     }
  725. }
  726.  
  727.  
  728. /* Shoot a bolt in a given direction            -RAK-    */
  729. void fire_bolt(typ, dir, y, x, dam, bolt_typ)
  730. int typ, dir, y, x, dam;
  731. char *bolt_typ;
  732. {
  733.   int i, oldy, oldx, dist, flag;
  734.   int32u weapon_type; int harm_type;
  735.   int (*dummy)();
  736.   register cave_type *c_ptr;
  737.   register monster_type *m_ptr;
  738.   register creature_type *r_ptr;
  739.   vtype out_val, m_name;
  740.  
  741.   flag = FALSE;
  742.   get_flags(typ, &weapon_type, &harm_type, &dummy);
  743.   oldy = y;
  744.   oldx = x;
  745.   dist = 0;
  746.   do
  747.     {
  748.       (void) mmove(dir, &y, &x);
  749.       dist++;
  750.       c_ptr = &cave[y][x];
  751.       lite_spot(oldy, oldx);
  752.       if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
  753.     flag = TRUE;
  754.       else
  755.     {
  756.       if (c_ptr->cptr > 1)
  757.         {
  758.           flag = TRUE;
  759.           m_ptr = &m_list[c_ptr->cptr];
  760.           r_ptr = &c_list[m_ptr->mptr];
  761.  
  762.           /* light up monster and draw monster, temporarily set
  763.          pl so that update_mon() will work */
  764.           i = c_ptr->pl;
  765.           c_ptr->pl = TRUE;
  766.           update_mon ((int)c_ptr->cptr);
  767.           c_ptr->pl = i;
  768.           /* draw monster and clear previous bolt */
  769.           put_qio();
  770.  
  771.           lower_monster_name(m_name, m_ptr, r_ptr);
  772.           (void) sprintf(out_val, "The %s strikes %s.", bolt_typ, m_name);
  773.           msg_print(out_val);
  774.           if (harm_type & r_ptr->cdefense)
  775.         {
  776.           dam = dam*2;
  777.           if (m_ptr->ml)
  778.             c_recall[m_ptr->mptr].r_cdefense |= harm_type;
  779.         }
  780.           else if (weapon_type & r_ptr->spells)
  781.         {
  782.           dam = dam / 4;
  783.           if (m_ptr->ml)
  784.             c_recall[m_ptr->mptr].r_spells |= weapon_type;
  785.         }
  786.           monster_name(m_name, m_ptr, r_ptr);
  787.           i = mon_take_hit((int)c_ptr->cptr, dam);
  788.           if (i >= 0)
  789.         {
  790.           (void) sprintf(out_val, "%s dies in a fit of agony.",
  791.                  m_name);
  792.           msg_print(out_val);
  793.           prt_experience();
  794.         }
  795.           else if (dam > 0)
  796.         {
  797.           (void) sprintf (out_val, "%s screams in agony.", m_name);
  798.           msg_print (out_val);
  799.         }
  800.         }
  801.       else if (panel_contains(y, x) && (py.flags.blind < 1))
  802.         {
  803.           print('*', y, x);
  804.           /* show the bolt */
  805.           put_qio();
  806.         }
  807.     }
  808.       oldy = y;
  809.       oldx = x;
  810.     }
  811.   while (!flag);
  812. }
  813.  
  814.  
  815. /* Shoot a ball in a given direction.  Note that balls have an    */
  816. /* area affect.                          -RAK-   */
  817. void fire_ball(typ, dir, y, x, dam_hp, descrip)
  818. int typ, dir, y, x, dam_hp;
  819. char *descrip;
  820. {
  821.   register int i, j;
  822.   int dam, max_dis, thit, tkill, k, tmp;
  823.   int oldy, oldx, dist, flag, harm_type;
  824.   int32u weapon_type;
  825.   int (*destroy)();
  826.   register cave_type *c_ptr;
  827.   register monster_type *m_ptr;
  828.   register creature_type *r_ptr;
  829.   vtype out_val;
  830.  
  831.   thit     = 0;
  832.   tkill     = 0;
  833.   max_dis = 2;
  834.   get_flags(typ, &weapon_type, &harm_type, &destroy);
  835.   flag = FALSE;
  836.   oldy = y;
  837.   oldx = x;
  838.   dist = 0;
  839.   do
  840.     {
  841.       (void) mmove(dir, &y, &x);
  842.       dist++;
  843.       lite_spot(oldy, oldx);
  844.       if (dist > OBJ_BOLT_RANGE)
  845.     flag = TRUE;
  846.       else
  847.     {
  848.       c_ptr = &cave[y][x];
  849.       if ((c_ptr->fval >= MIN_CLOSED_SPACE) || (c_ptr->cptr > 1))
  850.         {
  851.           flag = TRUE;
  852.           if (c_ptr->fval >= MIN_CLOSED_SPACE)
  853.         {
  854.           y = oldy;
  855.           x = oldx;
  856.         }
  857.           /* The ball hits and explodes.             */
  858.           /* The explosion.                 */
  859.           for (i = y-max_dis; i <= y+max_dis; i++)
  860.         for (j = x-max_dis; j <= x+max_dis; j++)
  861.           if (in_bounds(i, j) && (distance(y, x, i, j) <= max_dis)
  862.               && los(y, x, i, j))
  863.             {
  864.               c_ptr = &cave[i][j];
  865.               if ((c_ptr->tptr != 0) &&
  866.               (*destroy)(&t_list[c_ptr->tptr]))
  867.             (void) delete_object(i, j);
  868.               if (c_ptr->fval <= MAX_OPEN_SPACE)
  869.             {
  870.               if (c_ptr->cptr > 1)
  871.                 {
  872.                   m_ptr = &m_list[c_ptr->cptr];
  873.                   r_ptr = &c_list[m_ptr->mptr];
  874.  
  875.                   /* lite up creature if visible, temp
  876.                  set pl so that update_mon works */
  877.                   tmp = c_ptr->pl;
  878.                   c_ptr->pl = TRUE;
  879.                   update_mon((int)c_ptr->cptr);
  880.  
  881.                   thit++;
  882.                   dam = dam_hp;
  883.                   if (harm_type & r_ptr->cdefense)
  884.                 {
  885.                   dam = dam*2;
  886.                   if (m_ptr->ml)
  887.                     c_recall[m_ptr->mptr].r_cdefense |=harm_type;
  888.                 }
  889.                   else if (weapon_type & r_ptr->spells)
  890.                 {
  891.                   dam = dam / 4;
  892.                   if (m_ptr->ml)
  893.                     c_recall[m_ptr->mptr].r_spells |=weapon_type;
  894.                 }
  895.                   dam = (dam/(distance(i, j, y, x)+1));
  896.                   k = mon_take_hit((int)c_ptr->cptr, dam);
  897.                   if (k >= 0)
  898.                 tkill++;
  899.                   c_ptr->pl = tmp;
  900.                 }
  901.               else if (panel_contains(i, j) &&(py.flags.blind < 1))
  902.                 print('*', i, j);
  903.             }
  904.             }
  905.           /* show ball of whatever */
  906.           put_qio();
  907.  
  908.           for (i = (y - 2); i <= (y + 2); i++)
  909.         for (j = (x - 2); j <= (x + 2); j++)
  910.           if (in_bounds(i, j) && panel_contains(i, j) &&
  911.               (distance(y, x, i, j) <= max_dis))
  912.             lite_spot(i, j);
  913.  
  914.           /* End  explosion.             */
  915.           if (thit == 1)
  916.         {
  917.           (void) sprintf(out_val,
  918.                  "The %s envelops a creature!",
  919.                  descrip);
  920.           msg_print(out_val);
  921.         }
  922.           else if (thit > 1)
  923.         {
  924.           (void) sprintf(out_val,
  925.                  "The %s envelops several creatures!",
  926.                  descrip);
  927.           msg_print(out_val);
  928.         }
  929.           if (tkill == 1)
  930.         msg_print("There is a scream of agony!");
  931.           else if (tkill > 1)
  932.         msg_print("There are several screams of agony!");
  933.           if (tkill >= 0)
  934.         prt_experience();
  935.           /* End ball hitting.             */
  936.         }
  937.       else if (panel_contains(y, x) && (py.flags.blind < 1))
  938.         {
  939.           print('*', y, x);
  940.           /* show bolt */
  941.           put_qio();
  942.         }
  943.       oldy = y;
  944.       oldx = x;
  945.     }
  946.     }
  947.   while (!flag);
  948. }
  949.  
  950.  
  951. /* Breath weapon works like a fire_ball, but affects the player. */
  952. /* Note the area affect.                  -RAK-   */
  953. void breath(typ, y, x, dam_hp, ddesc, monptr)
  954. int typ, y, x, dam_hp;
  955. char *ddesc;
  956. int monptr;
  957. {
  958.   register int i, j;
  959.   int dam, max_dis, harm_type;
  960.   int32u weapon_type;
  961.   int32u tmp, treas;
  962.   int (*destroy)();
  963.   register cave_type *c_ptr;
  964.   register monster_type *m_ptr;
  965.   register creature_type *r_ptr;
  966. #ifdef ATARIST_MWC
  967.   int32u holder;
  968. #endif
  969.  
  970.   max_dis = 2;
  971.   get_flags(typ, &weapon_type, &harm_type, &destroy);
  972.   for (i = y-2; i <= y+2; i++)
  973.     for (j = x-2; j <= x+2; j++)
  974.       if (in_bounds(i, j) && (distance(y, x, i, j) <= max_dis)
  975.       && los(y, x, i, j))
  976.     {
  977.       c_ptr = &cave[i][j];
  978.       if ((c_ptr->tptr != 0) &&
  979.           (*destroy)(&t_list[c_ptr->tptr]))
  980.         (void) delete_object(i, j);
  981.       if (c_ptr->fval <= MAX_OPEN_SPACE)
  982.         {
  983.           /* must test status bit, not py.flags.blind here, flag could have
  984.          been set by a previous monster, but the breath should still
  985.          be visible until the blindness takes effect */
  986.           if (panel_contains(i, j) && !(py.flags.status & PY_BLIND))
  987.         print('*', i, j);
  988.           if (c_ptr->cptr > 1)
  989.         {
  990.           m_ptr = &m_list[c_ptr->cptr];
  991.           r_ptr = &c_list[m_ptr->mptr];
  992.           dam = dam_hp;
  993.           if (harm_type & r_ptr->cdefense)
  994.             dam = dam*2;
  995.           else if (weapon_type & r_ptr->spells)
  996.             dam = (dam / 4);
  997.           dam = (dam/(distance(i, j, y, x)+1));
  998.           /* can not call mon_take_hit here, since player does not
  999.              get experience for kill */
  1000.           m_ptr->hp = m_ptr->hp - dam;
  1001.           m_ptr->csleep = 0;
  1002.           if (m_ptr->hp < 0)
  1003.             {
  1004.               treas = monster_death((int)m_ptr->fy, (int)m_ptr->fx,
  1005.                         r_ptr->cmove);
  1006.               if (m_ptr->ml)
  1007.             {
  1008. #ifdef ATARIST_MWC
  1009.               holder = CM_TREASURE;
  1010.               tmp = (c_recall[m_ptr->mptr].r_cmove & holder)
  1011.                 >> CM_TR_SHIFT;
  1012.               if (tmp > ((treas & holder) >> CM_TR_SHIFT))
  1013.                 treas = (treas & ~holder)|(tmp << CM_TR_SHIFT);
  1014.               c_recall[m_ptr->mptr].r_cmove = treas |
  1015.                 (c_recall[m_ptr->mptr].r_cmove & ~holder);
  1016. #else
  1017.               tmp = (c_recall[m_ptr->mptr].r_cmove & CM_TREASURE)
  1018.                 >> CM_TR_SHIFT;
  1019.               if (tmp > ((treas & CM_TREASURE) >> CM_TR_SHIFT))
  1020.                 treas = (treas & ~CM_TREASURE)|(tmp<<CM_TR_SHIFT);
  1021.               c_recall[m_ptr->mptr].r_cmove = treas |
  1022.                 (c_recall[m_ptr->mptr].r_cmove & ~CM_TREASURE);
  1023. #endif
  1024.             }
  1025.  
  1026.               /* It ate an already processed monster.Handle normally.*/
  1027.               if (monptr < c_ptr->cptr)
  1028.             delete_monster((int) c_ptr->cptr);
  1029.               /* If it eats this monster, an already processed monster
  1030.              will take its place, causing all kinds of havoc.
  1031.              Delay the kill a bit. */
  1032.               else
  1033.             fix1_delete_monster((int) c_ptr->cptr);
  1034.             }
  1035.         }
  1036.           else if (c_ptr->cptr == 1)
  1037.         {
  1038.           dam = (dam_hp/(distance(i, j, y, x)+1));
  1039.           /* let's do at least one point of damage */
  1040.           /* prevents randint(0) problem with poison_gas, also */
  1041.           if (dam == 0)
  1042.             dam = 1;
  1043.           switch(typ)
  1044.             {
  1045.             case GF_LIGHTNING: light_dam(dam, ddesc); break;
  1046.             case GF_POISON_GAS: poison_gas(dam, ddesc); break;
  1047.             case GF_ACID: acid_dam(dam, ddesc); break;
  1048.             case GF_FROST: cold_dam(dam, ddesc); break;
  1049.             case GF_FIRE: fire_dam(dam, ddesc); break;
  1050.             }
  1051.         }
  1052.         }
  1053.     }
  1054.   /* show the ball of gas */
  1055.   put_qio();
  1056.  
  1057.   for (i = (y - 2); i <= (y + 2); i++)
  1058.     for (j = (x - 2); j <= (x + 2); j++)
  1059.       if (in_bounds(i, j) && panel_contains(i, j) &&
  1060.       (distance(y, x, i, j) <= max_dis))
  1061.     lite_spot(i, j);
  1062. }
  1063.  
  1064.  
  1065. /* Recharge a wand, staff, or rod.  Sometimes the item breaks. -RAK-*/
  1066. int recharge(num)
  1067. register int num;
  1068. {
  1069.   int i, j, item_val;
  1070.   register int res;
  1071.   register inven_type *i_ptr;
  1072.  
  1073.   res = FALSE;
  1074.   if (!find_range(TV_STAFF, TV_WAND, &i, &j))
  1075.     msg_print("You have nothing to recharge.");
  1076.   else if (get_item(&item_val, "Recharge which item?", i, j, CNIL, CNIL))
  1077.     {
  1078.       i_ptr = &inventory[item_val];
  1079.       res = TRUE;
  1080.       /* recharge I = recharge(20) = 1/6 failure for empty 10th level wand */
  1081.       /* recharge II = recharge(60) = 1/10 failure for empty 10th level wand*/
  1082.       /* make it harder to recharge high level, and highly charged wands, note
  1083.      that i can be negative, so check its value before trying to call
  1084.      randint().  */
  1085.       i = num + 50 - (int)i_ptr->level - i_ptr->p1;
  1086.       if (i < 19)
  1087.     i = 1;    /* Automatic failure.  */
  1088.       else
  1089.     i = randint (i/10);
  1090.  
  1091.       if (i == 1)
  1092.     {
  1093.       msg_print("There is a bright flash of light.");
  1094.       inven_destroy(item_val);
  1095.     }
  1096.       else
  1097.     {
  1098.       num = (num/(i_ptr->level+2)) + 1;
  1099.       i_ptr->p1 += 2 + randint(num);
  1100.       if (known2_p(i_ptr))
  1101.         clear_known2(i_ptr);
  1102.       clear_empty(i_ptr);
  1103.     }
  1104.     }
  1105.   return(res);
  1106. }
  1107.  
  1108.  
  1109. /* Increase or decrease a creatures hit points        -RAK-    */
  1110. int hp_monster(dir, y, x, dam)
  1111. int dir, y, x, dam;
  1112. {
  1113.   register int i;
  1114.   int flag, dist, monster;
  1115.   register cave_type *c_ptr;
  1116.   register monster_type *m_ptr;
  1117.   register creature_type *r_ptr;
  1118.   vtype out_val, m_name;
  1119.  
  1120.   monster = FALSE;
  1121.   flag = FALSE;
  1122.   dist = 0;
  1123.   do
  1124.     {
  1125.       (void) mmove(dir, &y, &x);
  1126.       dist++;
  1127.       c_ptr = &cave[y][x];
  1128.       if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
  1129.     flag = TRUE;
  1130.       else if (c_ptr->cptr > 1)
  1131.     {
  1132.       flag = TRUE;
  1133.       m_ptr = &m_list[c_ptr->cptr];
  1134.       r_ptr = &c_list[m_ptr->mptr];
  1135.       monster_name (m_name, m_ptr, r_ptr);
  1136.       monster = TRUE;
  1137.       i = mon_take_hit((int)c_ptr->cptr, dam);
  1138.       if (i >= 0)
  1139.         {
  1140.           (void) sprintf(out_val, "%s dies in a fit of agony.", m_name);
  1141.           msg_print(out_val);
  1142.           prt_experience();
  1143.         }
  1144.       else if (dam > 0)
  1145.         {
  1146.           (void) sprintf(out_val, "%s screams in agony.", m_name);
  1147.           msg_print(out_val);
  1148.         }
  1149.     }
  1150.     }
  1151.   while (!flag);
  1152.   return(monster);
  1153. }
  1154.  
  1155.  
  1156. /* Drains life; note it must be living.        -RAK-    */
  1157. int drain_life(dir, y, x)
  1158. int dir, y, x;
  1159. {
  1160.   register int i;
  1161.   int flag, dist, drain;
  1162.   register cave_type *c_ptr;
  1163.   register monster_type *m_ptr;
  1164.   register creature_type *r_ptr;
  1165.   vtype out_val, m_name;
  1166.  
  1167.   drain = FALSE;
  1168.   flag = FALSE;
  1169.   dist = 0;
  1170.   do
  1171.     {
  1172.       (void) mmove(dir, &y, &x);
  1173.       dist++;
  1174.       c_ptr = &cave[y][x];
  1175.       if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
  1176.     flag = TRUE;
  1177.       else if (c_ptr->cptr > 1)
  1178.     {
  1179.       flag = TRUE;
  1180.       m_ptr = &m_list[c_ptr->cptr];
  1181.       r_ptr = &c_list[m_ptr->mptr];
  1182.       if ((r_ptr->cdefense & CD_UNDEAD) == 0)
  1183.         {
  1184.           drain = TRUE;
  1185.           monster_name (m_name, m_ptr, r_ptr);
  1186.           i = mon_take_hit((int)c_ptr->cptr, 75);
  1187.           if (i >= 0)
  1188.         {
  1189.           (void) sprintf(out_val, "%s dies in a fit of agony.",m_name);
  1190.           msg_print(out_val);
  1191.           prt_experience();
  1192.         }
  1193.           else
  1194.         {
  1195.           (void) sprintf(out_val, "%s screams in agony.", m_name);
  1196.           msg_print(out_val);
  1197.         }
  1198.         }
  1199.       else
  1200.         c_recall[m_ptr->mptr].r_cdefense |= CD_UNDEAD;
  1201.     }
  1202.     }
  1203.   while (!flag);
  1204.   return(drain);
  1205. }
  1206.  
  1207.  
  1208. /* Increase or decrease a creatures speed        -RAK-    */
  1209. /* NOTE: cannot slow a winning creature (BALROG)         */
  1210. int speed_monster(dir, y, x, spd)
  1211. int dir, y, x, spd;
  1212. {
  1213.   int flag, dist, speed;
  1214.   register cave_type *c_ptr;
  1215.   register monster_type *m_ptr;
  1216.   register creature_type *r_ptr;
  1217.   vtype out_val, m_name;
  1218.  
  1219.   speed = FALSE;
  1220.   flag = FALSE;
  1221.   dist = 0;
  1222.   do
  1223.     {
  1224.       (void) mmove(dir, &y, &x);
  1225.       dist++;
  1226.       c_ptr = &cave[y][x];
  1227.       if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
  1228.     flag = TRUE;
  1229.       else if (c_ptr->cptr > 1)
  1230.     {
  1231.       flag = TRUE;
  1232.       m_ptr = &m_list[c_ptr->cptr];
  1233.       r_ptr = &c_list[m_ptr->mptr];
  1234.       monster_name (m_name, m_ptr, r_ptr);
  1235.       if (spd > 0)
  1236.         {
  1237.           m_ptr->cspeed += spd;
  1238.           m_ptr->csleep = 0;
  1239.           (void) sprintf (out_val, "%s starts moving faster.", m_name);
  1240.           msg_print (out_val);
  1241.           speed = TRUE;
  1242.         }
  1243.       else if (randint(MAX_MONS_LEVEL) > r_ptr->level)
  1244.         {
  1245.           m_ptr->cspeed += spd;
  1246.           m_ptr->csleep = 0;
  1247.           (void) sprintf (out_val, "%s starts moving slower.", m_name);
  1248.           msg_print (out_val);
  1249.           speed = TRUE;
  1250.         }
  1251.       else
  1252.         {
  1253.           m_ptr->csleep = 0;
  1254.           (void) sprintf(out_val, "%s is unaffected.", m_name);
  1255.           msg_print(out_val);
  1256.         }
  1257.     }
  1258.     }
  1259.   while (!flag);
  1260.   return(speed);
  1261. }
  1262.  
  1263.  
  1264. /* Confuse a creature                    -RAK-    */
  1265. int confuse_monster(dir, y, x)
  1266. int dir, y, x;
  1267. {
  1268.   int flag, dist, confuse;
  1269.   register cave_type *c_ptr;
  1270.   register monster_type *m_ptr;
  1271.   register creature_type *r_ptr;
  1272.   vtype out_val, m_name;
  1273.  
  1274.   confuse = FALSE;
  1275.   flag = FALSE;
  1276.   dist = 0;
  1277.   do
  1278.     {
  1279.       (void) mmove(dir, &y, &x);
  1280.       dist++;
  1281.       c_ptr = &cave[y][x];
  1282.       if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
  1283.     flag = TRUE;
  1284.       else if (c_ptr->cptr > 1)
  1285.     {
  1286.       m_ptr = &m_list[c_ptr->cptr];
  1287.       r_ptr = &c_list[m_ptr->mptr];
  1288.       monster_name (m_name, m_ptr, r_ptr);
  1289.       flag = TRUE;
  1290.       if ((randint(MAX_MONS_LEVEL) < r_ptr->level) ||
  1291.           (CD_NO_SLEEP & r_ptr->cdefense))
  1292.         {
  1293.           if (m_ptr->ml && (r_ptr->cdefense & CD_NO_SLEEP))
  1294.         c_recall[m_ptr->mptr].r_cdefense |= CD_NO_SLEEP;
  1295.           /* Monsters which resisted the attack should wake up.
  1296.          Monsters with inane resistence ignore the attack.  */
  1297.           if (! (CD_NO_SLEEP & r_ptr->cdefense))
  1298.         m_ptr->csleep = 0;
  1299.           (void) sprintf(out_val, "%s is unaffected.", m_name);
  1300.           msg_print(out_val);
  1301.         }
  1302.       else
  1303.         {
  1304.           m_ptr->confused = TRUE;
  1305.           confuse = TRUE;
  1306.           m_ptr->csleep = 0;
  1307.           (void) sprintf(out_val, "%s appears confused.", m_name);
  1308.           msg_print(out_val);
  1309.         }
  1310.     }
  1311.     }
  1312.   while (!flag);
  1313.   return(confuse);
  1314. }
  1315.  
  1316.  
  1317. /* Sleep a creature.                    -RAK-    */
  1318. int sleep_monster(dir, y, x)
  1319. int dir, y, x;
  1320. {
  1321.   int flag, dist, sleep;
  1322.   register cave_type *c_ptr;
  1323.   register monster_type *m_ptr;
  1324.   register creature_type *r_ptr;
  1325.   vtype out_val, m_name;
  1326.  
  1327.   sleep = FALSE;
  1328.   flag = FALSE;
  1329.   dist = 0;
  1330.   do
  1331.     {
  1332.       (void) mmove(dir, &y, &x);
  1333.       dist++;
  1334.       c_ptr = &cave[y][x];
  1335.       if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
  1336.     flag = TRUE;
  1337.       else if (c_ptr->cptr > 1)
  1338.     {
  1339.       m_ptr = &m_list[c_ptr->cptr];
  1340.       r_ptr = &c_list[m_ptr->mptr];
  1341.       flag = TRUE;
  1342.       monster_name (m_name, m_ptr, r_ptr);
  1343.       if ((randint(MAX_MONS_LEVEL) < r_ptr->level) ||
  1344.           (CD_NO_SLEEP & r_ptr->cdefense))
  1345.         {
  1346.           if (m_ptr->ml && (r_ptr->cdefense & CD_NO_SLEEP))
  1347.         c_recall[m_ptr->mptr].r_cdefense |= CD_NO_SLEEP;
  1348.           (void) sprintf(out_val, "%s is unaffected.", m_name);
  1349.           msg_print(out_val);
  1350.         }
  1351.       else
  1352.         {
  1353.           m_ptr->csleep = 500;
  1354.           sleep = TRUE;
  1355.           (void) sprintf(out_val, "%s falls asleep.", m_name);
  1356.           msg_print(out_val);
  1357.         }
  1358.     }
  1359.     }
  1360.   while (!flag);
  1361.   return(sleep);
  1362. }
  1363.  
  1364.  
  1365. /* Turn stone to mud, delete wall.            -RAK-    */
  1366. int wall_to_mud(dir, y, x)
  1367. int dir, y, x;
  1368. {
  1369.   int i, wall, dist;
  1370.   bigvtype out_val, tmp_str;
  1371.   register int flag;
  1372.   register cave_type *c_ptr;
  1373.   register monster_type *m_ptr;
  1374.   register creature_type *r_ptr;
  1375.   vtype m_name;
  1376.  
  1377.   wall = FALSE;
  1378.   flag = FALSE;
  1379.   dist = 0;
  1380.   do
  1381.     {
  1382.       (void) mmove(dir, &y, &x);
  1383.       dist++;
  1384.       c_ptr = &cave[y][x];
  1385.       /* note, this ray can move through walls as it turns them to mud */
  1386.       if (dist == OBJ_BOLT_RANGE)
  1387.     flag = TRUE;
  1388.       if ((c_ptr->fval >= MIN_CAVE_WALL) && (c_ptr->fval != BOUNDARY_WALL))
  1389.     {
  1390.       flag = TRUE;
  1391.       (void) twall(y, x, 1, 0);
  1392.       if (test_light(y, x))
  1393.         {
  1394.           msg_print("The wall turns into mud.");
  1395.           wall = TRUE;
  1396.         }
  1397.     }
  1398.       else if ((c_ptr->tptr != 0) && (c_ptr->fval >= MIN_CLOSED_SPACE))
  1399.     {
  1400.       flag = TRUE;
  1401.       if (panel_contains(y, x) && test_light(y, x))
  1402.         {
  1403.           objdes(tmp_str, &t_list[c_ptr->tptr], FALSE);
  1404.           (void) sprintf(out_val, "The %s turns into mud.", tmp_str);
  1405.           msg_print(out_val);
  1406.           wall = TRUE;
  1407.         }
  1408.       (void) delete_object(y, x);
  1409.     }
  1410.       if (c_ptr->cptr > 1)
  1411.     {
  1412.       m_ptr = &m_list[c_ptr->cptr];
  1413.       r_ptr = &c_list[m_ptr->mptr];
  1414.       if (CD_STONE & r_ptr->cdefense)
  1415.         {
  1416.           monster_name (m_name, m_ptr, r_ptr);
  1417.           i = mon_take_hit((int)c_ptr->cptr, 100);
  1418.           /* Should get these messages even if the monster is not
  1419.          visible.  */
  1420.           if (i >= 0)
  1421.         {
  1422.           c_recall[i].r_cdefense |= CD_STONE;
  1423.           (void) sprintf(out_val, "%s dissolves!", m_name);
  1424.           msg_print(out_val);
  1425.           prt_experience(); /* print msg before calling prt_exp */
  1426.         }
  1427.           else
  1428.         {
  1429.           c_recall[m_ptr->mptr].r_cdefense |= CD_STONE;
  1430.           (void) sprintf(out_val, "%s grunts in pain!",m_name);
  1431.           msg_print(out_val);
  1432.         }
  1433.           flag = TRUE;
  1434.         }
  1435.     }
  1436.     }
  1437.   while (!flag);
  1438.   return(wall);
  1439. }
  1440.  
  1441.  
  1442. /* Destroy all traps and doors in a given direction    -RAK-    */
  1443. int td_destroy2(dir, y, x)
  1444. int dir, y, x;
  1445. {
  1446.   register int destroy2, dist;
  1447.   register cave_type *c_ptr;
  1448.   register inven_type *t_ptr;
  1449.  
  1450.   destroy2 = FALSE;
  1451.   dist= 0;
  1452.   do
  1453.     {
  1454.       (void) mmove(dir, &y, &x);
  1455.       dist++;
  1456.       c_ptr = &cave[y][x];
  1457.       /* must move into first closed spot, as it might be a secret door */
  1458.       if (c_ptr->tptr != 0)
  1459.     {
  1460.       t_ptr = &t_list[c_ptr->tptr];
  1461.       if ((t_ptr->tval == TV_INVIS_TRAP) || (t_ptr->tval == TV_CLOSED_DOOR)
  1462.           || (t_ptr->tval == TV_VIS_TRAP) || (t_ptr->tval == TV_OPEN_DOOR)
  1463.           || (t_ptr->tval == TV_SECRET_DOOR))
  1464.         {
  1465.           if (delete_object(y, x))
  1466.         {
  1467.           msg_print("There is a bright flash of light!");
  1468.           destroy2 = TRUE;
  1469.         }
  1470.         }
  1471.       else if (t_ptr->tval == TV_CHEST)
  1472.         {
  1473.           msg_print("Click!");
  1474.           t_ptr->flags &= ~(CH_TRAPPED|CH_LOCKED);
  1475.           destroy2 = TRUE;
  1476.           t_ptr->name2 = SN_UNLOCKED;
  1477.           known2(t_ptr);
  1478.         }
  1479.     }
  1480.     }
  1481.   while ((dist <= OBJ_BOLT_RANGE) || c_ptr->fval <= MAX_OPEN_SPACE);
  1482.   return(destroy2);
  1483. }
  1484.  
  1485.  
  1486. /* Polymorph a monster                    -RAK-    */
  1487. /* NOTE: cannot polymorph a winning creature (BALROG)         */
  1488. int poly_monster(dir, y, x)
  1489. int dir, y, x;
  1490. {
  1491.   int dist, flag, poly;
  1492.   register cave_type *c_ptr;
  1493.   register creature_type *r_ptr;
  1494.   register monster_type *m_ptr;
  1495.   vtype out_val, m_name;
  1496.  
  1497.   poly = FALSE;
  1498.   flag = FALSE;
  1499.   dist = 0;
  1500.   do
  1501.     {
  1502.       (void) mmove(dir, &y, &x);
  1503.       dist++;
  1504.       c_ptr = &cave[y][x];
  1505.       if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
  1506.     flag = TRUE;
  1507.       else if (c_ptr->cptr > 1)
  1508.     {
  1509.       m_ptr = &m_list[c_ptr->cptr];
  1510.       r_ptr = &c_list[m_ptr->mptr];
  1511.       if (randint(MAX_MONS_LEVEL) > r_ptr->level)
  1512.         {
  1513.           flag = TRUE;
  1514.           delete_monster((int)c_ptr->cptr);
  1515.           /* Place_monster() should always return TRUE here.  */
  1516.           poly = place_monster(y, x,
  1517.                    randint(m_level[MAX_MONS_LEVEL]-m_level[0])
  1518.                    - 1 + m_level[0], FALSE);
  1519.           /* don't test c_ptr->fm here, only pl/tl */
  1520.           if (poly && panel_contains(y, x) && (c_ptr->tl || c_ptr->pl))
  1521.         poly = TRUE;
  1522.         }
  1523.       else
  1524.         {
  1525.           monster_name (m_name, m_ptr, r_ptr);
  1526.           (void) sprintf(out_val, "%s is unaffected.", m_name);
  1527.           msg_print(out_val);
  1528.         }
  1529.     }
  1530.     }
  1531.   while (!flag);
  1532.   return(poly);
  1533. }
  1534.  
  1535.  
  1536. /* Create a wall.                    -RAK-    */
  1537. int build_wall(dir, y, x)
  1538. int dir, y, x;
  1539. {
  1540.   register int i;
  1541.   int build, damage, dist, flag;
  1542.   register cave_type *c_ptr;
  1543.   register monster_type *m_ptr;
  1544.   register creature_type *r_ptr;
  1545.   vtype m_name, out_val;
  1546. #ifdef ATARIST_MWC
  1547.   int32u holder;
  1548. #endif
  1549.  
  1550.   build = FALSE;
  1551.   dist = 0;
  1552.   flag = FALSE;
  1553.   do
  1554.     {
  1555.       (void) mmove(dir, &y, &x);
  1556.       dist++;
  1557.       c_ptr = &cave[y][x];
  1558.       if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
  1559.     flag = TRUE;
  1560.       else
  1561.     {
  1562.       if (c_ptr->tptr != 0)
  1563.         (void) delete_object(y, x);
  1564.       if (c_ptr->cptr > 1)
  1565.         {
  1566.           /* stop the wall building */
  1567.           flag = TRUE;
  1568.           m_ptr = &m_list[c_ptr->cptr];
  1569.           r_ptr = &c_list[m_ptr->mptr];
  1570.  
  1571. #ifdef ATARIST_MWC
  1572.           if (!(r_ptr->cmove & (holder = CM_PHASE)))
  1573. #else
  1574.           if (!(r_ptr->cmove & CM_PHASE))
  1575. #endif
  1576.         {
  1577.           /* monster does not move, can't escape the wall */
  1578.           if (r_ptr->cmove & CM_ATTACK_ONLY)
  1579.             damage = 3000; /* this will kill everything */
  1580.           else
  1581.             damage = damroll (4, 8);
  1582.  
  1583.           monster_name (m_name, m_ptr, r_ptr);
  1584.           (void) sprintf (out_val, "%s wails out in pain!", m_name);
  1585.           msg_print (out_val);
  1586.           i = mon_take_hit((int)c_ptr->cptr, damage);
  1587.           if (i >= 0)
  1588.             {
  1589.               (void) sprintf (out_val, "%s is embedded in the rock.",
  1590.                       m_name);
  1591.               msg_print (out_val);
  1592.               prt_experience();
  1593.             }
  1594.         }
  1595.           else if (r_ptr->cchar == 'E' || r_ptr->cchar == 'X')
  1596.         {
  1597.           /* must be an earth elemental or an earth spirit, or a Xorn
  1598.              increase its hit points */
  1599.           m_ptr->hp += damroll(4, 8);
  1600.         }
  1601.         }
  1602.       c_ptr->fval  = MAGMA_WALL;
  1603.       c_ptr->fm = FALSE;
  1604.       /* Permanently light this wall if it is lit by player's lamp.  */
  1605.       c_ptr->pl = (c_ptr->tl || c_ptr->pl);
  1606.       lite_spot(y, x);
  1607.       i++;
  1608.       build = TRUE;
  1609.     }
  1610.     }
  1611.   while (!flag);
  1612.   return(build);
  1613. }
  1614.  
  1615.  
  1616. /* Replicate a creature                    -RAK-    */
  1617. int clone_monster(dir, y, x)
  1618. int dir, y, x;
  1619. {
  1620.   register cave_type *c_ptr;
  1621.   register int dist, flag;
  1622.  
  1623.   dist = 0;
  1624.   flag = FALSE;
  1625.   do
  1626.     {
  1627.       (void) mmove(dir, &y, &x);
  1628.       dist++;
  1629.       c_ptr = &cave[y][x];
  1630.       if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
  1631.     flag = TRUE;
  1632.       else if (c_ptr->cptr > 1)
  1633.     {
  1634.       m_list[c_ptr->cptr].csleep = 0;
  1635.       /* monptr of 0 is safe here, since can't reach here from creatures */
  1636.       return multiply_monster(y, x, (int)m_list[c_ptr->cptr].mptr, 0);
  1637.     }
  1638.     }
  1639.   while (!flag);
  1640.   return(FALSE);
  1641. }
  1642.  
  1643.  
  1644. /* Move the creature record to a new location        -RAK-    */
  1645. void teleport_away(monptr, dis)
  1646. int monptr, dis;
  1647. {
  1648.   register int yn, xn, ctr;
  1649.   register monster_type *m_ptr;
  1650.  
  1651.   m_ptr = &m_list[monptr];
  1652.   ctr = 0;
  1653.   do
  1654.     {
  1655.       do
  1656.     {
  1657.       yn = m_ptr->fy + (randint(2*dis+1) - (dis + 1));
  1658.       xn = m_ptr->fx + (randint(2*dis+1) - (dis + 1));
  1659.     }
  1660.       while (!in_bounds(yn, xn));
  1661.       ctr++;
  1662.       if (ctr > 9)
  1663.     {
  1664.       ctr = 0;
  1665.       dis += 5;
  1666.     }
  1667.     }
  1668.   while ((cave[yn][xn].fval >= MIN_CLOSED_SPACE) || (cave[yn][xn].cptr != 0));
  1669.   move_rec((int)m_ptr->fy, (int)m_ptr->fx, yn, xn);
  1670.   lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
  1671.   m_ptr->fy = yn;
  1672.   m_ptr->fx = xn;
  1673.   /* this is necessary, because the creature is not currently visible
  1674.      in its new position */
  1675.   m_ptr->ml = FALSE;
  1676.   m_ptr->cdis = distance (char_row, char_col, yn, xn);
  1677.   update_mon (monptr);
  1678. }
  1679.  
  1680.  
  1681. /* Teleport player to spell casting creature        -RAK-    */
  1682. void teleport_to(ny, nx)
  1683. int ny, nx;
  1684. {
  1685.   int dis, ctr, y, x;
  1686.   register int i, j;
  1687.   register cave_type *c_ptr;
  1688.  
  1689.   dis = 1;
  1690.   ctr = 0;
  1691.   do
  1692.     {
  1693.       y = ny + (randint(2*dis+1) - (dis + 1));
  1694.       x = nx + (randint(2*dis+1) - (dis + 1));
  1695.       ctr++;
  1696.       if (ctr > 9)
  1697.     {
  1698.       ctr = 0;
  1699.       dis++;
  1700.     }
  1701.     }
  1702.   while (!in_bounds(y, x) || (cave[y][x].fval >= MIN_CLOSED_SPACE)
  1703.      || (cave[y][x].cptr >= 2));
  1704.   move_rec(char_row, char_col, y, x);
  1705.   for (i = char_row-1; i <= char_row+1; i++)
  1706.     for (j = char_col-1; j <= char_col+1; j++)
  1707.       {
  1708.     c_ptr = &cave[i][j];
  1709.     c_ptr->tl = FALSE;
  1710.     lite_spot(i, j);
  1711.       }
  1712.   lite_spot(char_row, char_col);
  1713.   char_row = y;
  1714.   char_col = x;
  1715.   check_view();
  1716.   /* light creatures */
  1717.   creatures(FALSE);
  1718. }
  1719.  
  1720.  
  1721. /* Teleport all creatures in a given direction away    -RAK-    */
  1722. int teleport_monster(dir, y, x)
  1723. int dir, y, x;
  1724. {
  1725.   register int flag, result, dist;
  1726.   register cave_type *c_ptr;
  1727.  
  1728.   flag = FALSE;
  1729.   result = FALSE;
  1730.   dist = 0;
  1731.   do
  1732.     {
  1733.       (void) mmove(dir, &y, &x);
  1734.       dist++;
  1735.       c_ptr = &cave[y][x];
  1736.       if ((dist > OBJ_BOLT_RANGE) || c_ptr->fval >= MIN_CLOSED_SPACE)
  1737.     flag = TRUE;
  1738.       else if (c_ptr->cptr > 1)
  1739.     {
  1740.       m_list[c_ptr->cptr].csleep = 0; /* wake it up */
  1741.       teleport_away((int)c_ptr->cptr, MAX_SIGHT);
  1742.       result = TRUE;
  1743.     }
  1744.     }
  1745.   while (!flag);
  1746.   return(result);
  1747. }
  1748.  
  1749.  
  1750. /* Delete all creatures within max_sight distance    -RAK-    */
  1751. /* NOTE : Winning creatures cannot be genocided             */
  1752. int mass_genocide()
  1753. {
  1754.   register int i, result;
  1755.   register monster_type *m_ptr;
  1756.   register creature_type *r_ptr;
  1757. #ifdef ATARIST_MWC
  1758.   int32u holder;
  1759. #endif
  1760.  
  1761.   result = FALSE;
  1762.   for (i = mfptr - 1; i >= MIN_MONIX; i--)
  1763.     {
  1764.       m_ptr = &m_list[i];
  1765.       r_ptr = &c_list[m_ptr->mptr];
  1766. #ifdef ATARIST_MWC
  1767.       if ((m_ptr->cdis <= MAX_SIGHT) &&
  1768.       ((r_ptr->cmove & (holder = CM_WIN)) == 0))
  1769. #else
  1770.       if ((m_ptr->cdis <= MAX_SIGHT) && ((r_ptr->cmove & CM_WIN) == 0))
  1771. #endif
  1772.     {
  1773.       delete_monster(i);
  1774.       result = TRUE;
  1775.     }
  1776.     }
  1777.   return(result);
  1778. }
  1779.  
  1780. /* Delete all creatures of a given type from level.    -RAK-    */
  1781. /* This does not keep creatures of type from appearing later.     */
  1782. /* NOTE : Winning creatures can not be genocided. */
  1783. int genocide()
  1784. {
  1785.   register int i, killed;
  1786.   char typ;
  1787.   register monster_type *m_ptr;
  1788.   register creature_type *r_ptr;
  1789.   vtype out_val;
  1790. #ifdef ATARIST_MWC
  1791.   int32u holder;
  1792. #endif
  1793.  
  1794.   killed = FALSE;
  1795.   if (get_com("Which type of creature do you wish exterminated?", &typ))
  1796.     for (i = mfptr - 1; i >= MIN_MONIX; i--)
  1797.       {
  1798.     m_ptr = &m_list[i];
  1799.     r_ptr = &c_list[m_ptr->mptr];
  1800.     if (typ == c_list[m_ptr->mptr].cchar)
  1801. #ifdef ATARIST_MWC
  1802.       if ((r_ptr->cmove & (holder = CM_WIN)) == 0)
  1803. #else
  1804.       if ((r_ptr->cmove & CM_WIN) == 0)
  1805. #endif
  1806.         {
  1807.           delete_monster(i);
  1808.           killed = TRUE;
  1809.         }
  1810.       else
  1811.         {
  1812.           /* genocide is a powerful spell, so we will let the player
  1813.          know the names of the creatures he did not destroy,
  1814.          this message makes no sense otherwise */
  1815.           (void) sprintf(out_val, "The %s is unaffected.", r_ptr->name);
  1816.           msg_print(out_val);
  1817.         }
  1818.       }
  1819.   return(killed);
  1820. }
  1821.  
  1822.  
  1823. /* Change speed of any creature .            -RAK-    */
  1824. /* NOTE: cannot slow a winning creature (BALROG)         */
  1825. int speed_monsters(spd)
  1826. int spd;
  1827. {
  1828.   register int i, speed;
  1829.   register monster_type *m_ptr;
  1830.   register creature_type *r_ptr;
  1831.   vtype out_val, m_name;
  1832.  
  1833.   speed = FALSE;
  1834.   for (i = mfptr - 1; i >= MIN_MONIX; i--)
  1835.     {
  1836.       m_ptr = &m_list[i];
  1837.       r_ptr = &c_list[m_ptr->mptr];
  1838.       monster_name (m_name, m_ptr, r_ptr);
  1839.  
  1840.       if ((m_ptr->cdis > MAX_SIGHT) ||
  1841.       !los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx))
  1842.     /* do nothing */
  1843.     ;
  1844.       else if (spd > 0)
  1845.     {
  1846.       m_ptr->cspeed += spd;
  1847.       m_ptr->csleep = 0;
  1848.       if (m_ptr->ml)
  1849.         {
  1850.           speed = TRUE;
  1851.           (void) sprintf (out_val, "%s starts moving faster.", m_name);
  1852.           msg_print (out_val);
  1853.         }
  1854.     }
  1855.       else if (randint(MAX_MONS_LEVEL) > r_ptr->level)
  1856.     {
  1857.       m_ptr->cspeed += spd;
  1858.       m_ptr->csleep = 0;
  1859.       if (m_ptr->ml)
  1860.         {
  1861.           (void) sprintf (out_val, "%s starts moving slower.", m_name);
  1862.           msg_print (out_val);
  1863.           speed = TRUE;
  1864.         }
  1865.     }
  1866.       else if (m_ptr->ml)
  1867.     {
  1868.       m_ptr->csleep = 0;
  1869.       (void) sprintf(out_val, "%s is unaffected.", m_name);
  1870.       msg_print(out_val);
  1871.     }
  1872.     }
  1873.   return(speed);
  1874. }
  1875.  
  1876.  
  1877. /* Sleep any creature .        -RAK-    */
  1878. int sleep_monsters2()
  1879. {
  1880.   register int i, sleep;
  1881.   register monster_type *m_ptr;
  1882.   register creature_type *r_ptr;
  1883.   vtype out_val, m_name;
  1884.  
  1885.   sleep = FALSE;
  1886.   for (i = mfptr - 1; i >= MIN_MONIX; i--)
  1887.     {
  1888.       m_ptr = &m_list[i];
  1889.       r_ptr = &c_list[m_ptr->mptr];
  1890.       monster_name (m_name, m_ptr, r_ptr);
  1891.       if ((m_ptr->cdis > MAX_SIGHT) || 
  1892.       !los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx))
  1893.     /* do nothing */
  1894.     ;
  1895.       else if ((randint(MAX_MONS_LEVEL) < r_ptr->level) ||
  1896.       (CD_NO_SLEEP & r_ptr->cdefense))
  1897.     {
  1898.       if (m_ptr->ml)
  1899.         {
  1900.           if (r_ptr->cdefense & CD_NO_SLEEP)
  1901.         c_recall[m_ptr->mptr].r_cdefense |= CD_NO_SLEEP;
  1902.           (void) sprintf(out_val, "%s is unaffected.", m_name);
  1903.           msg_print(out_val);
  1904.         }
  1905.     }
  1906.       else
  1907.     {
  1908.       m_ptr->csleep = 500;
  1909.       if (m_ptr->ml)
  1910.         {
  1911.           (void) sprintf(out_val, "%s falls asleep.", m_name);
  1912.           msg_print(out_val);
  1913.           sleep = TRUE;
  1914.         }
  1915.     }
  1916.     }
  1917.   return(sleep);
  1918. }
  1919.  
  1920.  
  1921. /* Polymorph any creature that player can see.    -RAK-    */
  1922. /* NOTE: cannot polymorph a winning creature (BALROG)         */
  1923. int mass_poly()
  1924. {
  1925.   register int i;
  1926.   int y, x, mass;
  1927.   register monster_type *m_ptr;
  1928.   register creature_type *r_ptr;
  1929. #ifdef ATARIST_MWC
  1930.   int32u holder;
  1931. #endif
  1932.  
  1933.   mass = FALSE;
  1934.   for (i = mfptr - 1; i >= MIN_MONIX; i--)
  1935.     {
  1936.       m_ptr = &m_list[i];
  1937.       if (m_ptr->cdis <= MAX_SIGHT)
  1938.     {
  1939.       r_ptr = &c_list[m_ptr->mptr];
  1940. #ifdef ATARIST_MWC
  1941.       if ((r_ptr->cmove & (holder = CM_WIN)) == 0)
  1942. #else
  1943.       if ((r_ptr->cmove & CM_WIN) == 0)
  1944. #endif
  1945.         {
  1946.           y = m_ptr->fy;
  1947.           x = m_ptr->fx;
  1948.           delete_monster(i);
  1949.           /* Place_monster() should always return TRUE here.  */
  1950.           mass = place_monster(y, x,
  1951.                    randint(m_level[MAX_MONS_LEVEL]-m_level[0])
  1952.                    - 1 + m_level[0], FALSE);
  1953.         }
  1954.     }
  1955.     }
  1956.   return(mass);
  1957. }
  1958.  
  1959.  
  1960. /* Display evil creatures on current panel        -RAK-    */
  1961. int detect_evil()
  1962. {
  1963.   register int i, flag;
  1964.   register monster_type *m_ptr;
  1965.  
  1966.   flag = FALSE;
  1967.   for (i = mfptr - 1; i >= MIN_MONIX; i--)
  1968.     {
  1969.       m_ptr = &m_list[i];
  1970.       if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx) &&
  1971.       (CD_EVIL & c_list[m_ptr->mptr].cdefense))
  1972.     {
  1973.       m_ptr->ml = TRUE;
  1974.       /* works correctly even if hallucinating */
  1975.       print((char)c_list[m_ptr->mptr].cchar, (int)m_ptr->fy,
  1976.         (int)m_ptr->fx);
  1977.       flag = TRUE;
  1978.     }
  1979.     }
  1980.   if (flag)
  1981.     {
  1982.       msg_print("You sense the presence of evil!");
  1983.       msg_print(CNIL);
  1984.       /* must unlight every monster just lighted */
  1985.       creatures(FALSE);
  1986.     }
  1987.   return(flag);
  1988. }
  1989.  
  1990.  
  1991. /* Change players hit points in some manner        -RAK-    */
  1992. int hp_player(num)
  1993. int num;
  1994. {
  1995.   register int res;
  1996.   register struct misc *m_ptr;
  1997.  
  1998.   res = FALSE;
  1999.   m_ptr = &py.misc;
  2000.   if (m_ptr->chp < m_ptr->mhp)
  2001.     {
  2002.       m_ptr->chp += num;
  2003.       if (m_ptr->chp > m_ptr->mhp)
  2004.     {
  2005.       m_ptr->chp = m_ptr->mhp;
  2006.       m_ptr->chp_frac = 0;
  2007.     }
  2008.       prt_chp();
  2009.  
  2010.       num = num / 5;
  2011.       if (num < 3) {
  2012.     if (num == 0) msg_print("You feel a little better.");
  2013.     else          msg_print("You feel better.");
  2014.       } else {
  2015.     if (num < 7) msg_print("You feel much better.");
  2016.     else         msg_print("You feel very good.");
  2017.       }
  2018.       res = TRUE;
  2019.     }
  2020.   return(res);
  2021. }
  2022.  
  2023.  
  2024. /* Cure players confusion                -RAK-    */
  2025. int cure_confusion()
  2026. {
  2027.   register int cure;
  2028.   register struct flags *f_ptr;
  2029.  
  2030.   cure = FALSE;
  2031.   f_ptr = &py.flags;
  2032.   if (f_ptr->confused > 1)
  2033.     {
  2034.       f_ptr->confused = 1;
  2035.       cure = TRUE;
  2036.     }
  2037.   return(cure);
  2038. }
  2039.  
  2040.  
  2041. /* Cure players blindness                -RAK-    */
  2042. int cure_blindness()
  2043. {
  2044.   register int cure;
  2045.   register struct flags *f_ptr;
  2046.  
  2047.   cure = FALSE;
  2048.   f_ptr = &py.flags;
  2049.   if (f_ptr->blind > 1)
  2050.     {
  2051.       f_ptr->blind = 1;
  2052.       cure = TRUE;
  2053.     }
  2054.   return(cure);
  2055. }
  2056.  
  2057.  
  2058. /* Cure poisoning                    -RAK-    */
  2059. int cure_poison()
  2060. {
  2061.   register int cure;
  2062.   register struct flags *f_ptr;
  2063.  
  2064.   cure = FALSE;
  2065.   f_ptr = &py.flags;
  2066.   if (f_ptr->poisoned > 1)
  2067.     {
  2068.       f_ptr->poisoned = 1;
  2069.       cure = TRUE;
  2070.     }
  2071.   return(cure);
  2072. }
  2073.  
  2074.  
  2075. /* Cure the players fear                -RAK-    */
  2076. int remove_fear()
  2077. {
  2078.   register int result;
  2079.   register struct flags *f_ptr;
  2080.  
  2081.   result = FALSE;
  2082.   f_ptr = &py.flags;
  2083.   if (f_ptr->afraid > 1)
  2084.     {
  2085.       f_ptr->afraid = 1;
  2086.       result = TRUE;
  2087.     }
  2088.   return(result);
  2089. }
  2090.  
  2091.  
  2092. /* This is a fun one.  In a given block, pick some walls and    */
  2093. /* turn them into open spots.  Pick some open spots and turn     */
  2094. /* them into walls.  An "Earthquake" effect.           -RAK-   */
  2095. void earthquake()
  2096. {
  2097.   register int i, j;
  2098.   register cave_type *c_ptr;
  2099.   register monster_type *m_ptr;
  2100.   register creature_type *r_ptr;
  2101.   int damage, tmp;
  2102.   vtype out_val, m_name;
  2103. #ifdef ATARIST_MWC
  2104.   int32u holder;
  2105. #endif
  2106.  
  2107.   for (i = char_row-8; i <= char_row+8; i++)
  2108.     for (j = char_col-8; j <= char_col+8; j++)
  2109.       if (((i != char_row) || (j != char_col)) &&
  2110.       in_bounds(i, j) && (randint(8) == 1))
  2111.     {
  2112.       c_ptr = &cave[i][j];
  2113.       if (c_ptr->tptr != 0)
  2114.         (void) delete_object(i, j);
  2115.       if (c_ptr->cptr > 1)
  2116.         {
  2117.           m_ptr = &m_list[c_ptr->cptr];
  2118.           r_ptr = &c_list[m_ptr->mptr];
  2119.  
  2120. #ifdef ATARIST_MWC
  2121.           if (!(r_ptr->cmove & (holder = CM_PHASE)))
  2122. #else
  2123.           if (!(r_ptr->cmove & CM_PHASE))
  2124. #endif
  2125.         {
  2126.           if(r_ptr->cmove & CM_ATTACK_ONLY)
  2127.             damage = 3000; /* this will kill everything */
  2128.           else
  2129.             damage = damroll (4, 8);
  2130.  
  2131.           monster_name (m_name, m_ptr, r_ptr);
  2132.           (void) sprintf (out_val, "%s wails out in pain!", m_name);
  2133.           msg_print (out_val);
  2134.           i = mon_take_hit((int)c_ptr->cptr, damage);
  2135.           if (i >= 0)
  2136.             {
  2137.               (void) sprintf (out_val, "%s is embedded in the rock.",
  2138.                       m_name);
  2139.               msg_print (out_val);
  2140.               prt_experience();
  2141.             }
  2142.         }
  2143.           else if (r_ptr->cchar == 'E' || r_ptr->cchar == 'X')
  2144.         {
  2145.           /* must be an earth elemental or an earth spirit, or a Xorn
  2146.              increase its hit points */
  2147.           m_ptr->hp += damroll(4, 8);
  2148.         }
  2149.         }
  2150.  
  2151.       if ((c_ptr->fval >= MIN_CAVE_WALL) && (c_ptr->fval != BOUNDARY_WALL))
  2152.         {
  2153.           c_ptr->fval  = CORR_FLOOR;
  2154.           c_ptr->pl = FALSE;
  2155.           c_ptr->fm = FALSE;
  2156.         }
  2157.       else if (c_ptr->fval <= MAX_CAVE_FLOOR)
  2158.         {
  2159.           tmp = randint(10);
  2160.           if (tmp < 6)
  2161.         c_ptr->fval  = QUARTZ_WALL;
  2162.           else if (tmp < 9)
  2163.         c_ptr->fval  = MAGMA_WALL;
  2164.           else
  2165.         c_ptr->fval  = GRANITE_WALL;
  2166.  
  2167.           c_ptr->fm = FALSE;
  2168.         }
  2169.       lite_spot(i, j);
  2170.     }
  2171. }
  2172.  
  2173.  
  2174. /* Evil creatures don't like this.               -RAK-   */
  2175. int protect_evil()
  2176. {
  2177.   register int res;
  2178.   register struct flags *f_ptr;
  2179.  
  2180.   f_ptr = &py.flags;
  2181.   if (f_ptr->protevil == 0)
  2182.     res = TRUE;
  2183.   else
  2184.     res = FALSE;
  2185.   f_ptr->protevil += randint(25) + 3*py.misc.lev;
  2186.   return(res);
  2187. }
  2188.  
  2189.  
  2190. /* Create some high quality mush for the player.    -RAK-    */
  2191. void create_food()
  2192. {
  2193.   register cave_type *c_ptr;
  2194.  
  2195.   c_ptr = &cave[char_row][char_col];
  2196.   if (c_ptr->tptr != 0)
  2197.     {
  2198.       /* take no action here, don't want to destroy object under player */
  2199.       msg_print ("There is already an object under you.");
  2200.       /* set free_turn_flag so that scroll/spell points won't be used */
  2201.       free_turn_flag = TRUE;
  2202.     }
  2203.   else
  2204.     {
  2205.       place_object(char_row, char_col);
  2206.       invcopy(&t_list[c_ptr->tptr], OBJ_MUSH);
  2207.     }
  2208. }
  2209.  
  2210.  
  2211. /* Attempts to destroy a type of creature.  Success depends on    */
  2212. /* the creatures level VS. the player's level         -RAK-     */
  2213. int dispel_creature(cflag, damage)
  2214. int cflag;
  2215. int damage;
  2216. {
  2217.   register int i;
  2218.   int k, dispel;
  2219.   register monster_type *m_ptr;
  2220.   register creature_type *r_ptr;
  2221.   vtype out_val, m_name;
  2222.  
  2223.   dispel = FALSE;
  2224.   for (i = mfptr - 1; i >= MIN_MONIX; i--)
  2225.     {
  2226.       m_ptr = &m_list[i];
  2227.       if ((m_ptr->cdis <= MAX_SIGHT) &&
  2228.       (cflag & c_list[m_ptr->mptr].cdefense) &&
  2229.       los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx))
  2230.     {
  2231.       r_ptr = &c_list[m_ptr->mptr];
  2232.       c_recall[m_ptr->mptr].r_cdefense |= cflag;
  2233.       monster_name (m_name, m_ptr, r_ptr);
  2234.       k = mon_take_hit (i, randint(damage));
  2235.       /* Should get these messages even if the monster is not
  2236.          visible.  */
  2237.       if (k >= 0)
  2238.         (void) sprintf(out_val, "%s dissolves!", m_name);
  2239.       else
  2240.         (void) sprintf(out_val, "%s shudders.", m_name);
  2241.       msg_print(out_val);
  2242.       dispel = TRUE;
  2243.       if (k >= 0)
  2244.         prt_experience();
  2245.     }
  2246.     }
  2247.   return(dispel);
  2248. }
  2249.  
  2250.  
  2251. /* Attempt to turn (confuse) undead creatures.    -RAK-    */
  2252. int turn_undead()
  2253. {
  2254.   register int i, turn_und;
  2255.   register monster_type *m_ptr;
  2256.   register creature_type *r_ptr;
  2257.   vtype out_val, m_name;
  2258.  
  2259.   turn_und = FALSE;
  2260.   for (i = mfptr - 1; i >= MIN_MONIX; i--)
  2261.     {
  2262.       m_ptr = &m_list[i];
  2263.       r_ptr = &c_list[m_ptr->mptr];
  2264.       if ((m_ptr->cdis <= MAX_SIGHT) &&
  2265.       (CD_UNDEAD & r_ptr->cdefense) &&
  2266.       (los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx)))
  2267.     {
  2268.       monster_name (m_name, m_ptr, r_ptr);
  2269.       if (((py.misc.lev+1) > r_ptr->level) ||
  2270.           (randint(5) == 1))
  2271.         {
  2272.           if (m_ptr->ml)
  2273.         {
  2274.           (void) sprintf(out_val, "%s runs frantically!", m_name);
  2275.           msg_print(out_val);
  2276.           turn_und = TRUE;
  2277.           c_recall[m_ptr->mptr].r_cdefense |= CD_UNDEAD;
  2278.         }
  2279.           m_ptr->confused = TRUE;
  2280.         }
  2281.       else if (m_ptr->ml)
  2282.         {
  2283.           (void) sprintf(out_val, "%s is unaffected.", m_name);
  2284.           msg_print(out_val);
  2285.         }
  2286.     }
  2287.     }
  2288.   return(turn_und);
  2289. }
  2290.  
  2291.  
  2292. /* Leave a glyph of warding. Creatures will not pass over! -RAK-*/
  2293. void warding_glyph()
  2294. {
  2295.   register int i;
  2296.   register cave_type *c_ptr;
  2297.  
  2298.   c_ptr = &cave[char_row][char_col];
  2299.   if (c_ptr->tptr == 0)
  2300.     {
  2301.       i = popt();
  2302.       c_ptr->tptr = i;
  2303.       invcopy(&t_list[i], OBJ_SCARE_MON);
  2304.     }
  2305. }
  2306.  
  2307.  
  2308. /* Lose a strength point.                -RAK-    */
  2309. void lose_str()
  2310. {
  2311.   if (!py.flags.sustain_str)
  2312.     {
  2313.       (void) dec_stat (A_STR);
  2314.       msg_print("You feel very sick.");
  2315.     }
  2316.   else
  2317.     msg_print("You feel sick for a moment,  it passes.");
  2318. }
  2319.  
  2320.  
  2321. /* Lose an intelligence point.                -RAK-    */
  2322. void lose_int()
  2323. {
  2324.   if (!py.flags.sustain_int)
  2325.     {
  2326.       (void) dec_stat(A_INT);
  2327.       msg_print("You become very dizzy.");
  2328.     }
  2329.   else
  2330.     msg_print("You become dizzy for a moment,  it passes.");
  2331. }
  2332.  
  2333.  
  2334. /* Lose a wisdom point.                    -RAK-    */
  2335. void lose_wis()
  2336. {
  2337.   if (!py.flags.sustain_wis)
  2338.     {
  2339.       (void) dec_stat(A_WIS);
  2340.       msg_print("You feel very naive.");
  2341.     }
  2342.   else
  2343.     msg_print("You feel naive for a moment,  it passes.");
  2344. }
  2345.  
  2346.  
  2347. /* Lose a dexterity point.                -RAK-    */
  2348. void lose_dex()
  2349. {
  2350.   if (!py.flags.sustain_dex)
  2351.     {
  2352.       (void) dec_stat(A_DEX);
  2353.       msg_print("You feel very sore.");
  2354.     }
  2355.   else
  2356.     msg_print("You feel sore for a moment,  it passes.");
  2357. }
  2358.  
  2359.  
  2360. /* Lose a constitution point.                -RAK-    */
  2361. void lose_con()
  2362. {
  2363.   if (!py.flags.sustain_con)
  2364.     {
  2365.       (void) dec_stat(A_CON);
  2366.       msg_print("You feel very sick.");
  2367.     }
  2368.   else
  2369.     msg_print("You feel sick for a moment,  it passes.");
  2370. }
  2371.  
  2372.  
  2373. /* Lose a charisma point.                -RAK-    */
  2374. void lose_chr()
  2375. {
  2376.   if (!py.flags.sustain_chr)
  2377.     {
  2378.       (void) dec_stat(A_CHR);
  2379.       msg_print("Your skin starts to itch.");
  2380.     }
  2381.   else
  2382.     msg_print("Your skin starts to itch, but feels better now.");
  2383. }
  2384.  
  2385.  
  2386. /* Lose experience                    -RAK-    */
  2387. void lose_exp(amount)
  2388. int32 amount;
  2389. {
  2390.   register int i;
  2391.   register struct misc *m_ptr;
  2392.   register class_type *c_ptr;
  2393.  
  2394.   m_ptr = &py.misc;
  2395.   if (amount > m_ptr->exp)
  2396.     m_ptr->exp = 0;
  2397.   else
  2398.     m_ptr->exp -= amount;
  2399.   prt_experience();
  2400.  
  2401.   i = 0;
  2402.   while ((player_exp[i] * m_ptr->expfact / 100) <= m_ptr->exp)
  2403.     i++;
  2404.   /* increment i once more, because level 1 exp is stored in player_exp[0] */
  2405.   i++;
  2406.  
  2407.   if (m_ptr->lev != i)
  2408.     {
  2409.       m_ptr->lev = i;
  2410.  
  2411.       calc_hitpoints();
  2412.       c_ptr = &class[m_ptr->pclass];
  2413.       if (c_ptr->spell == MAGE)
  2414.     {
  2415.       calc_spells(A_INT);
  2416.       calc_mana(A_INT);
  2417.     }
  2418.       else if (c_ptr->spell == PRIEST)
  2419.     {
  2420.       calc_spells(A_WIS);
  2421.       calc_mana(A_WIS);
  2422.     }
  2423.       prt_level();
  2424.       prt_title();
  2425.     }
  2426. }
  2427.  
  2428.  
  2429. /* Slow Poison                        -RAK-    */
  2430. int slow_poison()
  2431. {
  2432.   register int slow;
  2433.   register struct flags *f_ptr;
  2434.  
  2435.   slow = FALSE;
  2436.   f_ptr = &py.flags;
  2437.   if (f_ptr->poisoned > 0)
  2438.     {
  2439.       f_ptr->poisoned = f_ptr->poisoned / 2;
  2440.       if (f_ptr->poisoned < 1)    f_ptr->poisoned = 1;
  2441.       slow = TRUE;
  2442.       msg_print("The effect of the poison has been reduced.");
  2443.     }
  2444.   return(slow);
  2445. }
  2446.  
  2447.  
  2448. /* Bless                        -RAK-    */
  2449. void bless(amount)
  2450. int amount;
  2451. {
  2452.   py.flags.blessed += amount;
  2453. }
  2454.  
  2455.  
  2456. /* Detect Invisible for period of time            -RAK-    */
  2457. void detect_inv2(amount)
  2458. int amount;
  2459. {
  2460.   py.flags.detect_inv += amount;
  2461. }
  2462.  
  2463.  
  2464. static void replace_spot(y, x, typ)
  2465. int y, x, typ;
  2466. {
  2467.   register cave_type *c_ptr;
  2468.  
  2469.   c_ptr = &cave[y][x];
  2470.   switch(typ)
  2471.     {
  2472.     case 1: case 2: case 3:
  2473.       c_ptr->fval  = CORR_FLOOR;
  2474.       break;
  2475.     case 4: case 7: case 10:
  2476.       c_ptr->fval  = GRANITE_WALL;
  2477.       break;
  2478.     case 5: case 8: case 11:
  2479.       c_ptr->fval  = MAGMA_WALL;
  2480.       break;
  2481.     case 6: case 9: case 12:
  2482.       c_ptr->fval  = QUARTZ_WALL;
  2483.       break;
  2484.     }
  2485.   c_ptr->pl = FALSE;
  2486.   c_ptr->fm = FALSE;
  2487.   c_ptr->lr = FALSE;  /* this is no longer part of a room */
  2488.   if (c_ptr->tptr != 0)
  2489.     (void) delete_object(y, x);
  2490.   if (c_ptr->cptr > 1)
  2491.     delete_monster((int)c_ptr->cptr);
  2492. }
  2493.  
  2494.  
  2495. /* The spell of destruction.                -RAK-    */
  2496. /* NOTE : Winning creatures that are deleted will be considered     */
  2497. /*      as teleporting to another level.  This will NOT win the*/
  2498. /*      game.                               */
  2499. void destroy_area(y, x)
  2500. register int y, x;
  2501. {
  2502.   register int i, j, k;
  2503.  
  2504.   if (dun_level > 0)
  2505.     {
  2506.       for (i = (y-15); i <= (y+15); i++)
  2507.     for (j = (x-15); j <= (x+15); j++)
  2508.       if (in_bounds(i, j) && (cave[i][j].fval != BOUNDARY_WALL))
  2509.         {
  2510.           k = distance(i, j, y, x);
  2511.           if (k == 0) /* clear player's spot, but don't put wall there */
  2512.         replace_spot(i, j, 1);
  2513.           else if (k < 13)
  2514.         replace_spot(i, j, randint(6));
  2515.           else if (k < 16)
  2516.         replace_spot(i, j, randint(9));
  2517.         }
  2518.     }
  2519.   msg_print("There is a searing blast of light!");
  2520.   py.flags.blind += 10 + randint(10);
  2521. }
  2522.  
  2523.  
  2524. /* Enchants a plus onto an item.            -RAK-    */
  2525. int enchant(plusses, limit)
  2526. int16 *plusses;
  2527. int16 limit; /* maximum bonus allowed; usually 10, but weapon's maximum damage
  2528.         when enchanting melee weapons to damage */
  2529. {
  2530.   register int chance, res;
  2531.   
  2532.   if (limit <= 0) /* avoid randint(0) call */
  2533.     return(FALSE);
  2534.   chance = 0;
  2535.   res = FALSE;
  2536.   if (*plusses > 0)
  2537.     {
  2538.       chance = *plusses;
  2539.       if (randint(100) == 1) /* very rarely allow enchantment over limit */
  2540.     chance = randint(chance) - 1;
  2541.     }
  2542.   if (randint(limit) > chance)
  2543.     {
  2544.       *plusses += 1;
  2545.       res = TRUE;
  2546.     }
  2547.   return(res);
  2548. }
  2549.  
  2550.  
  2551. /* Removes curses from items in inventory        -RAK-    */
  2552. int remove_curse()
  2553. {
  2554.   register int i, result;
  2555.   register inven_type *i_ptr;
  2556. #ifdef ATARIST_MWC
  2557.   int32u holder = TR_CURSED;
  2558. #endif
  2559.  
  2560.   result = FALSE;
  2561.   for (i = INVEN_WIELD; i <= INVEN_OUTER; i++)
  2562.     {
  2563.       i_ptr = &inventory[i];
  2564. #ifdef ATARIST_MWC
  2565.       if (holder & i_ptr->flags)
  2566. #else
  2567.       if (TR_CURSED & i_ptr->flags)
  2568. #endif
  2569.     {
  2570. #ifdef ATARIST_MWC
  2571.       i_ptr->flags &= ~holder;
  2572. #else
  2573.       i_ptr->flags &= ~TR_CURSED;
  2574. #endif
  2575.       calc_bonuses();
  2576.       result = TRUE;
  2577.     }
  2578.     }
  2579.   return(result);
  2580. }
  2581.  
  2582.  
  2583. /* Restores any drained experience            -RAK-    */
  2584. int restore_level()
  2585. {
  2586.   register int restore;
  2587.   register struct misc *m_ptr;
  2588.  
  2589.   restore = FALSE;
  2590.   m_ptr = &py.misc;
  2591.   if (m_ptr->max_exp > m_ptr->exp)
  2592.     {
  2593.       restore = TRUE;
  2594.       msg_print("You feel your life energies returning.");
  2595.       /* this while loop is not redundant, ptr_exp may reduce the exp level */
  2596.       while (m_ptr->exp < m_ptr->max_exp)
  2597.     {
  2598.       m_ptr->exp = m_ptr->max_exp;
  2599.       prt_experience();
  2600.     }
  2601.     }
  2602.   return(restore);
  2603. }
  2604.